<?PHP
	/************************************************************************
	*       This file, in addition to all other parts of X7 Chat are        *
	*                   Copyright 2003-2007 by Tim Chamness.                *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* Version:          X7 Chat 3.0.0-A2                                    *
	* Release Date:     October 20, 2007                                    *
	* Author:           Tim Chamness                                        *
	* Copyright:        2003-2007 by Tim Chamness                           *
	* Website:          http://www.x7chat.com/                              *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* X7 Chat 3 is free software; you can redistribute it and/or modify     *
	* it under the terms of the GNU General Public License as published by  *
	* the Free Software Foundation; either version 3 of the License, or     *
	* (at your option) any later version.                                   *
	*                                                                       *
	* X7 Chat 3 is distributed in the hope that it will be useful, but      *
	* WITHOUT ANY WARRANTY; without even the implied warranty of            *
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
	* General Public License for more details.                              *
	*                                                                       *
	* You should have received a copy of the GNU General Public License     *
	* along with this program.  If not, see <http://www.gnu.org/licenses/>. *
	*                                                                       *
	* Additional Terms, compatible with Section 7 of the GNU GPL v3,        *
	* apply to X7 Chat 3 and all X7 Chat 3 files, including this one.       *
	* You should have received a copy of these Additional Terms in the      *
	* file docs/COPYING.ADDITIONAL_TERMS.  If you did not receive a copy    *
	* please visit <http://www.x7chat.com/COPYING.ADDITIONAL_TERMS/>.       *
	************************************************************************/

	/**
	 * This class is composed of static methods which handle IRC-style commands
	 * coming from the client.  Incidentally, this file also ends up handling
	 * things like the online list action menu.
	 * 
	 * To initiate an IRC-style command, call the process method
	 */
	class lib_irc {

		/**
		 * Process an IRC-style command
		 *
		 * @param string $msg The message in the form "/command arguments arguments arguments"
		 * @param Object $to The lib_room or lib_user that this message was sent to
		 * @param Array $output_stack Feedback messages in the form of JSON arrays are appended to this array
		 */
		public static function process($msg,$to,&$output_stack){
			
			// Break $msg up into space separated arguments
			$msg = explode(' ',$msg);
			
			// Remove / from the IRC command name
			$msg[0] = str_replace('/','',$msg[0]);
			
			// Count the number of space separated arguments
			$total_args = count($msg);
			
			// This is flipped to true if the user entered mismatched parenthesis
			$invalid_paren_error = false;
			
			// Iterate through all arguments and combine ones within quotation marks
			for($i = 1; $i < $total_args; $i++){
				
				// See if it is escaped
				if($msg[$i][0] == '"'){
					
					$alen = strlen($msg[$i]);
					if($alen == 1 && isset($msg[$i+1])){
						$msg[$i+1] = '"'.$msg[$i+1];
						unset($msg[$i]);
						continue;
					}
					
					$end = $alen > 6 ? substr($msg[$i],$alen-6) : str_pad($msg[$i],6,' ',STR_PAD_LEFT);
					$x = $i;
					while($end[5] != '"' || $end == '&#92;"'){
						$i++;
						
						if(!isset($msg[$i])){
							$invalid_paren_error = true;
							break 2;
						}
						
						$alen = strlen($msg[$i]);
						$end = $alen > 6 ? substr($msg[$i],$alen-6) : str_pad($msg[$i],6,' ',STR_PAD_LEFT);
						$msg[$x] .= ' '.$msg[$i];
						unset($msg[$i]);
					}
					
					$msg[$x] = str_replace('&#92;"',"&quot;",$msg[$x]);
					$msg[$x] = trim(str_replace('"','',$msg[$x]));
				}else{
					$end = $alen > 6 ? substr($msg[$i],$alen-6) : str_pad($msg[$i],6,' ',STR_PAD_LEFT);
					if($end[5] == '"' && $end != '&#92;"')
						$invalid_paren_error = true;
				}
				
			}
			
			if($invalid_paren_error){
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_messages->invalidparen,true);
				return;
			}
			
			$msg = array_values($msg);
			
			// Attempt to localize
			if(isset($GLOBALS['LANG']->lang_irc_commands->{'cmd_'.$msg[0]}))
				$msg[0] = $GLOBALS['LANG']->lang_irc_commands->{'cmd_'.$msg[0]};
			
			// Append irc_ prior to method call for safety reasons
			$msg[0] = 'irc_'.$msg[0];
			
			// Execute the action if it exists, otherwise throw an error
			if(!method_exists('lib_irc',$msg[0])){
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_messages->unknown_command,true);
			}else
				lib_irc::$msg[0]($msg,$to,$output_stack);
		}
		
		public static function irc_version($args,$to,&$output_stack){
			global $X7_CHAT_VERSION;
			$output_stack[] = lib_sending::send($to,null,$X7_CHAT_VERSION[1].' (Build '.$X7_CHAT_VERSION[0].')',true);
		}
		
		public static function irc_me($args,$to,&$output_stack){
			global $ses;
			unset($args[0]);
			$args = implode(' ',$args);
			if(empty($args))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->me_syntax,true);
			else
				$output_stack[] = lib_sending::send($to,null,$ses->user->data_cache['name'].' '.$args,false,true);
		}
		
		public static function irc_roll($args,$to,&$output_stack){
			global $ses;
			unset($args[0]);
			
			if(empty($args[1])){
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->roll_syntax,true);
				return;
			}
			
			$sides = (int)$args[1];
			if($sides < 2)
				$sides = 2;
			
			$msg = $GLOBALS['LANG']->lang_irc_commands->rolled;
			$msg = str_replace('_u',$ses->user->data_cache['name'],$msg);
			$msg = str_replace('_r',rand(1,$sides),$msg);
			$msg = str_replace('_s',$sides,$msg);
			
			$output_stack[] = lib_sending::send($to,null,$msg,false,true);
		}
		
		public static function irc_ignore($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->ignore_syntax,true);
			else{
				if($user = $ses->user->ignore_user($args[1]))
					$output_stack[] = lib_sending::send($to,null,str_replace('_u',$user->data_cache['name'],$GLOBALS['LANG']->lang_irc_commands->ignore_added),true);
				else
					$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->ignore_failed,true);
			}
		}
		
		public static function irc_unignore($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->unignore_syntax,true);
			else{
				if($user = $ses->user->unignore_user($args[1]))
					$output_stack[] = lib_sending::send($to,null,str_replace('_u',$user->data_cache['name'],$GLOBALS['LANG']->lang_irc_commands->ignore_removed),true);
				else
					$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->ignore_failed,true);
			}
		}
		
		public static function irc_addbuddy($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->addbuddy_syntax,true);
			else{
				if($user = $ses->user->add_buddy($args[1]))
					$output_stack[] = lib_sending::send($to,null,str_replace('_u',$user->data_cache['name'],$GLOBALS['LANG']->lang_irc_commands->buddylist_added),true);
				else
					$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->buddylist_fail,true);
			}
		}
		
		public static function irc_removebuddy($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->removebuddy_syntax,true);
			else{
				if($user = $ses->user->remove_buddy($args[1]))
					$output_stack[] = lib_sending::send($to,null,str_replace('_u',$user->data_cache['name'],$GLOBALS['LANG']->lang_irc_commands->buddylist_removed),true);
				else
					$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->buddylist_fail,true);
			}
		}
		
		public static function irc_kick($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->kick_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			else{
				$error = lib_room_extended::set_permissions_mode($to,$args[1],'user','kick');
				if($error !== lib_room_extended::E_NONE)
					$output_stack[] = lib_sending::send($to,null,lib_room_extended::get_error_message($error),true);
			}
		}
		
		public static function irc_mute($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->mute_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			else{
				$error = lib_room_extended::set_permissions_mode($to,$args[1],'user','mute');
				if($error !== lib_room_extended::E_NONE)
					$output_stack[] = lib_sending::send($to,null,lib_room_extended::get_error_message($error),true);
			}
		}
		
		public static function irc_unmute($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->unmute_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			else{
				$error = lib_room_extended::set_permissions_mode($to,$args[1],'user','unmute');
				if($error !== lib_room_extended::E_NONE)
					$output_stack[] = lib_sending::send($to,null,lib_room_extended::get_error_message($error),true);
			}
		}
		
		public static function irc_voice($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->voice_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			else{
				$error = lib_room_extended::set_permissions_mode($to,$args[1],'user','voice');
				if($error !== lib_room_extended::E_NONE)
					$output_stack[] = lib_sending::send($to,null,lib_room_extended::get_error_message($error),true);
			}
		}
		
		public static function irc_devoice($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->devoice_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			else{
				$error = lib_room_extended::set_permissions_mode($to,$args[1],'user','devoice');
				if($error !== lib_room_extended::E_NONE)
					$output_stack[] = lib_sending::send($to,null,lib_room_extended::get_error_message($error),true);
			}
		}
		
		public static function irc_moderator($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->moderator_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			else{
				$error = lib_room_extended::set_permissions_mode($to,$args[1],'user','moderator');
				if($error !== lib_room_extended::E_NONE)
					$output_stack[] = lib_sending::send($to,null,lib_room_extended::get_error_message($error),true);
			}
		}
		
		public static function irc_viewip($args,$to,&$output_stack){
			global $ses;
			if(empty($args[1]))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->viewip_syntax,true);
			elseif(get_class($to) != 'lib_room')
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_irc_commands->room_only_command,true);
			elseif(!$to->has_permission($ses->user,'VIEW_IP'))
				$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_messages->invalid_permissions,true);
			else{
				$user = new lib_user($args[1]);
				if(!$user->is_valid())
					$output_stack[] = lib_sending::send($to,null,$GLOBALS['LANG']->lang_messages->user_or_group_not_found,true);
				else{
					$ipmsg = str_replace('_a',$user->data_cache['ip'],str_replace('_u',$user->data_cache['name'],$GLOBALS['LANG']->lang_messages->ip_display));
					$output_stack[] = lib_sending::send($to,null,$ipmsg,true);
				}
			}
		}

	}
?>